home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
TeX 1995 July
/
TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO
/
macros
/
latex209
/
contrib
/
slatex
/
rnrscl.cl
< prev
next >
Wrap
Lisp/Scheme
|
1993-11-07
|
8KB
|
406 lines
;rnrscl.cl
;almost (but not quite!) simulates rnrs scheme in cl
;(c) Dorai Sitaram, December 1991, Rice University
;first make lambdas and applications Scheme-like
;by loading funval.cl
;i.e., no funcalls or #'s should be needed ever
;defining rnrs procedures and forms
(eval-when (compile load eval)
;the following names could clash
(shadow '(assoc let loop make-string map member nil peek-char read
read-char rem string t write)))
(defmacro set! (x v) `(setq ,x ,v))
(defmacro begin z `(progn ,@z))
(begin
;the boolean constants #t and #f
(set-dispatch-macro-character #\# #\t
(lambda (ign1 ign2 ign3) lisp:t))
(set-dispatch-macro-character #\# #\f
(lambda (ign1 ign2 ign3) lisp:nil))
;t and nil are now ordinary variables
(set! t lisp:t)
(set! nil lisp:nil))
(defconstant else
;for cond else clause
#t)
(define map mapcar)
;eq?
(define eq? eq)
;boolean?
(define boolean?
(lambda (b)
(or (eq? b #t) (eq? b #f))))
;symbol?
(define symbol?
(lambda (x)
;like symbolp but scheme doesn't consider booleans to be symbols
(and (symbolp x) (not (boolean? x)))))
;symbol->string
(define symbol->string symbol-name)
;char-ci=?
(define char-ci=? char-equal)
;string-ref
(define string-ref char)
;letrec
(defmacro letrec (pp . b)
`(lisp:let ,(map (lambda (p) `(,(car p) 'void))
pp)
,@(map (lambda (p)
`(set! ,(car p) ,(cadr p)))
pp)
,@b))
;named let with special treatment of loops (use variables with
;names beginning with 'loop only when you're sure that you're
;making calls to the named let proc only from tail positions).
(defmacro tail-recur (n let-pairs . b)
;tail-recur is like named let and defines a loop;
;it _requires_ that the loop be always called tail-recursively,
;otherwise the results are undefined
(let* ((x-s (map car let-pairs))
(y-s (map (lambda (x) (gensym)) x-s))
(tag (gensym)))
`(lisp:let ,let-pairs
(lisp:let ((,n (lambda ,y-s ;maybe macrolet would be better
,@(map
(lambda (x y)
`(set! ,x ,y))
x-s y-s)
(throw ',tag 'void))))
(lisp:loop
(catch ',tag
(return (begin ,@b))))))))
(defmacro recur (name let-pairs . body)
;named let
`(letrec ((,name (lambda ,(map car let-pairs) ,@body)))
(,name ,@(map cadr let-pairs))))
;let
(defmacro let (a . b)
;let includes named let;
;if named and the name starts with "loop...", then a
;tail-recursive loop is assumed
(cond ((and a (not (symbol? a))) `(lisp:let ,a ,@b))
((lisp:let ((s (symbol->string a)))
(and (>= (length s) 4)
(char-ci=? (string-ref s 0) #\l)
(char-ci=? (string-ref s 1) #\o)
(char-ci=? (string-ref s 2) #\o)
(char-ci=? (string-ref s 3) #\p)))
`(tail-recur ,a ,@b))
(else `(recur ,a ,@b))))
;equivalence predicates
(define eqv? eql)
(define equal? equal)
;pairs and lists
(define pair? consp)
(define set-car! rplaca)
(define set-cdr! rplacd)
(define null? null)
(define list?
(lambda (s)
;tests if s is a proper list;
;n.b. this is _not_ cl listp
(cond ((null? s) #t)
((pair? s) (list? (cdr s)))
(else #f))))
(define list-tail subseq)
(define list-ref elt)
(define sequence-set!
(lambda (s i v)
;sets the i-th element of sequence s to v
;not rnrs -- defined only as an auxiliary
(setf (elt s i) v)))
(define memq
(lambda (x s)
(lisp:member x s :test eq?)))
(define memv lisp:member)
(define member
(lambda (x s)
(lisp:member x s :test equal?)))
(define assq
(lambda (x s)
(lisp:assoc x s :test eq?)))
(define assv lisp:assoc)
(define assoc
(lambda (x s)
(lisp:assoc x s :test equal?)))
;symbols
(define string->symbol intern)
;numerical operations
(define number? numberp)
(define complex? complexp)
(define real? floatp)
(define rational? rationalp)
(define integer? integerp)
(define zero? zerop)
(define positive? plusp)
(define negative? minusp)
(define odd? oddp)
(define even? evenp)
(define quotient (lambda (m n) (truncate (/ m n))))
(define remainder lisp:rem)
(define modulo mod)
(define make-rectangular complex)
(define make-polar (lambda (r th) (* r (cis th))))
(define real-part realpart)
(define imag-part imagpart)
(define magnitude abs)
(define angle phase)
;numerical input and output
(define number->string
(lambda (n &optional b)
(if b (write-to-string n :base b)
(write-to-string n))))
(define string->number
(lambda (s &optional b)
(if b (let ((*read-base* b))
(with-input-from-string (p s)
(let ((n (lisp:read p)))
(if (number? n) n #f))))
(with-input-from-string (p s)
(let ((n (lisp:read p)))
(if (number? n) n #f))))))
;characters
(define char? characterp)
(define char=? char=)
(define char<? char<)
(define char>? char>)
(define char<=? char<=)
(define char>=? char>=)
(define char-ci<? char-lessp)
(define char-ci>? char-greaterp)
(define char-ci<=? char-not-greaterp)
(define char-ci>=? char-not-lessp)
(define char-alphabetic? alpha-char-p)
(define char-numeric? digit-char-p)
(define char-whitespace?
(lambda (c)
(or (char=? c #\space) (char=? c #\tab)
(not (graphic-char-p c)))))
(define char-upper-case? upper-case-p)
(define char-lower-case? lower-case-p)
(define char->integer char-int)
(define integer->char int-char)
;strings
(define string? stringp)
(define make-string
(lambda (n &optional c)
(lisp:make-string n :initial-element (if c c #\space))))
(define string
(lambda z
(concatenate 'lisp:string z)))
(define string-length length)
(define string-set! sequence-set!)
(define string=? string=)
(define string<? string<)
(define string>? string>)
(define string<=? string<=)
(define string>=? string>=)
(define string-ci=? string-equal)
(define string-ci<? string-lessp)
(define string-ci>? string-greaterp)
(define string-ci<=? string-not-greaterp)
(define string-ci>=? string-not-lessp)
(define substring subseq)
(define string-append
(lambda z
(apply concatenate 'lisp:string z)))
(define string->list
(lambda (s)
(concatenate 'list s)))
(define list->string
(lambda (s)
(concatenate 'lisp:string s)))
(define string-copy copy-seq) ;seq proc
(define string-fill! fill)
;vectors
(define vector? vectorp)
(define make-vector
(lambda (n &optional x)
(make-array (list n) :initial-element x)))
(define vector-length length)
(define vector-ref elt)
(define vector-set! sequence-set!)
(define vector->list
(lambda (v)
(concatenate 'list v)))
(define list->vector
(lambda (s)
(concatenate 'vector s)))
(define vector-fill! fill)
;control features
(define procedure? functionp)
(define for-each mapc)
(define call-with-current-continuation
(lambda (r)
;n.b. continuations are downward only
(let ((tag (gensym)))
(catch tag
(r (lambda (v) (throw tag v)))))))
;ports
(define call-with-input-file
(lambda (f pr)
(with-open-file (p f :direction :input)
(pr p))))
(define call-with-output-file
(lambda (f pr)
(with-open-file (p f :direction :output)
(pr p))))
(define input-port? input-stream-p)
(define output-port? output-stream-p)
(define current-input-port (lambda () *standard-input*))
(define current-output-port (lambda () *standard-output*))
(define with-input-from-file
(lambda (f th)
(call-with-input-file f
(lambda (p)
(let ((*standard-input* p)) ;fluid-let
(th))))))
(define with-output-to-file
(lambda (f th)
(call-with-output-file f
(lambda (p)
(let ((*standard-output* p)) ;fluid-let
(th))))))
(define open-input-file
(lambda (f)
(open f :direction :input)))
(define open-output-file
(lambda (f)
(open f :direction :output)))
(define close-input-port close)
(define close-output-port close)
;input
(define read
(lambda (&optional p)
(lisp:read p #f :end-of-file)))
(define read-char
(lambda (&optional p)
(lisp:read-char p #f :end-of-file)))
(define peek-char
(lambda (&optional p)
(lisp:peek-char #f p #f :end-of-file)))
(define eof-object?
(lambda (v)
(eq? v :end-of-file)))
(define char-ready?
(lambda (&optional p)
(let ((c (read-char-no-hang p #f #f)))
(if c (begin (unread-char c i) #t)
#f))))
;output
(define write prin1)
(define display princ)
(define newline terpri)
;system interface
(define transcript-on dribble)
(define transcript-off dribble)